package rpg.animation
{

	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	
	import rpg.Utils.Log;
	import rpg.animation.Animation;

	/**
	 * 动画组合成的动画类
	 * 例如人物朝北走的动画，由多个动画合成，包括全身体，武器等朝北走的动画
	 */
	public class ComposedAnimation extends AvatarAnimation
	{
		private static var point : Point = new Point();
		/**
		 * 需要合成的动画组
		 * 例如全身体，武器等朝北走的动画
		 */
		private var composingAnimations : Array;

		/**
		 * 根据几个动画合成的当前帧
		 */
		private var composedFrame : Frame = new Frame();

		/**
		 * 创建 合成动画
		 *
		 */
		public function ComposedAnimation(id : String , animations : Array , composedData : BitmapData , durations : Array , frameCount : int, centerX : int , centerY : int)
		{
			super(id);

			isNeedDownLoadAnimation = false;
			composingAnimations = animations;

			composedFrame = new Frame();
			composedFrame.data = composedData;
			composedFrame.offsetX = -composedData.width * .5;
			composedFrame.offsetY = -composedData.height;
			composedFrame.name = id;

			for(var i : int = 0 ; i < frameCount ; i += 1)
			{
				var frame : Frame = new Frame();
				frame.duration = durations[i];
				this.addFrame(frame);
			}
			
			this.centerX = centerX;
			this.centerY = centerY;
		}

		override public function gotoFrame(index : int) : Frame
		{
			curFrame = super.gotoFrame(index);

			if(curFrame.data == null)
			{
				curFrame = compose(index);
			}

			return curFrame;
		}

		override public function getFrame(index : int) : Frame
		{
			if(index < 0 || index >= frameCount)
				return null;
			var frame : Frame = super.getFrame(index);

			if(curFrame.data == null)
			{
				frame = compose(index);
			}
			return frame;
		}

		/**
		 * 合成动作Frame
		 * @param index
		 * @return
		 *
		 */
		private function compose(index : int) : Frame
		{
			//当该帧所有动画都加载完成后,才允许合成动画
			var canComposed : Boolean = true;
			var frame : Frame;
			var animationFrames : Dictionary = saveAnimationFrames;
			for each(var composing : Animation in composingAnimations)
			{
				frame = composing.getFrame(index);
				if(!frame || !frame.frameClass)
				{
					canComposed = false;
					break;
				}
			}
			if(!canComposed)
				return composedFrame;
			
			var bd : BitmapData = new BitmapData(centerX * 2 , centerY * 2 , true , 0);
			var boundRect : Rectangle = new Rectangle();
			boundRect.left = int.MAX_VALUE;
			boundRect.top = int.MAX_VALUE;
			boundRect.bottom = int.MIN_VALUE;
			boundRect.right = int.MIN_VALUE;

			for each(var animation : Animation in composingAnimations)
			{
				frame = animation.getFrame(index);
				if(!frame || !frame.frameClass)
					break;

				point.x = centerX + frame.offsetX;
				point.y = centerY + frame.offsetY;

				if(frame.data == null)
					frame.data = new frame.frameClass(0 , 0);
				//计算该合成帧的最小包围框
				bound(boundRect , point.x , point.y , frame.data.width , frame.data.rect.height);

				if(animation.filter || animation.colorTransform)
				{
					var tmpData : BitmapData = frame.data.clone();
					if(animation.filter)
						tmpData.applyFilter(frame.data , frame.data.rect , point , animation.filter);
					if(animation.colorTransform)
						tmpData.draw(tmpData , null , animation.colorTransform);
					bd.copyPixels(tmpData , tmpData.rect , point , null , null , true);
					tmpData.dispose();
				}
				else
				{
					bd.copyPixels(frame.data , frame.data.rect , point , null , null , true);
				}

				//再清除内存
				if(frame.data != null)
				{
					frame.data.dispose();
					frame.data = null;
				}
			}

			var bmd : BitmapData = new BitmapData(boundRect.width , boundRect.height , true , 0);
			point.x = 0;
			point.y = 0;
			bmd.copyPixels(bd , boundRect , point , null , null , true);
			bd.dispose();

			var tmpComposdFrame : Frame = super.getFrame(index);
			tmpComposdFrame.data = bmd;
			tmpComposdFrame.offsetX = boundRect.x - centerX;
			tmpComposdFrame.offsetY = boundRect.y - centerY;
			return tmpComposdFrame;
		}

		private function bound(dest : Rectangle , left : int , top : int , width : int , height : int) : void
		{
			var right : int = left + width;
			var bottom : int = top + height;
			if(left < dest.left)
				dest.left = left;
			if(top < dest.top)
				dest.top = top;
			if(right > dest.right)
				dest.right = right;
			if(bottom > dest.bottom)
				dest.bottom = bottom;
		}

		override public function destroy() : void
		{
			super.destroy();
			composingAnimations.length = 0;
			composingAnimations = null;
			composedFrame.destory();
			composedFrame = null;
		}
	}
}